package com.ecr.hub.front.bean.managed;

import java.util.Date;

import javax.annotation.Resource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.ecr.hub.ApplicationException;
import com.ecr.hub.InputDataException;
import com.ecr.hub.PlanNotFoundException;
import com.ecr.hub.RailNotFoundException;
import com.ecr.hub.SillonNotFoundException;
import com.ecr.hub.SillonTypeException;
import com.ecr.hub.WagonNotFoundException;
import com.ecr.hub.front.bean.AbstractManagedBean;
import com.ecr.hub.service.impression.pdf.IPdfManager;
import com.ecr.hub.util.MessageUtils;

@Controller("pdfManaged")
@Scope("request")
public class PdfManagedBean extends AbstractManagedBean {

	private static final long serialVersionUID = 1L;

	// Un objet qui permet de contenir l'ensemble des critères.
	private Criterion criterion;
	// Affiche ou non le pdf dans la page xhtml.
	private boolean displayPdf;
	// Le chemin d'un fichier à charger.
	private String pdfFileToLoad;

	// Le manager pour les pdf.
	@Resource(name = "pdfManager")
	IPdfManager pdfManager;

	/**
	 * Constructeur.
	 */
	PdfManagedBean() {
		criterion = new Criterion();
		criterion.setDate(new Date());
		criterion.setDateEnd(criterion.getDate());
	}

	/**
	 * Création d'un document pdf à partir d'une requête pour rechercher
	 * l'ensemble des sillons en départ ou arrivée pour une date donnée. Par
	 * défaut, on est à la date du jour. On vérifie si une plage d'heures a été
	 * rentrée par l'utilisateur.
	 */
	public void createPdfPlanning() {

		try {
			checkTime();
			setPdfFileToLoad(pdfManager
					.createPdfPLanning(LoginManagedBean.getConnectedUser(),
							getCriterion().getDate(), getCriterion()
									.getDateEnd(), getCriterion().getTime(),
							getCriterion().getTimeEnd(), getCriterion()
									.getTypeSillon()));
			setDisplayPdf(true);
		} catch (InputDataException e) {
			MessageUtils.setMessageError(e.getMessage());
		} catch (SillonNotFoundException e) {
			MessageUtils.setMessageInfo("msg.info.nodata");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Création d'un document pdf à partir d'une requête pour rechercher
	 * l'ensemble des wagons présents sur tout ou partie des voies, qu'ils
	 * soient en position réelle ou en position théorique.
	 */
	public void createPdfHub() {

		try {
			setPdfFileToLoad(pdfManager.createPdfHub(LoginManagedBean
					.getConnectedUser(), getCriterion().getTypeBundleId()));
			setDisplayPdf(true);
		} catch (RailNotFoundException e) {
			MessageUtils.setMessageInfo("msg.info.nodata");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Création d'un document pdf à partir d'une requête pour rechercher
	 * l'ensemble des wagons présents sur une voie, qu'ils soient en position
	 * réelle ou en position théorique.
	 */
	public void createPdfRail() {

		try {
			setPdfFileToLoad(pdfManager.createPdfRail(LoginManagedBean
					.getConnectedUser(), getCriterion().getPosRailId()));
			setDisplayPdf(true);
		} catch (WagonNotFoundException e) {
			MessageUtils.setMessageInfo("msg.info.nodata");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Créationd'un document pdf à partir d'une requête pour rechercher un
	 * programme de travail à partir d'un couple sillon / date ou directement à
	 * partir du tcms-train id. Pas de validator car il s'agit de champs couplés
	 * (on sépare pour être plus lisible). On vérifie par ailleurs que le
	 * programme de travail a bien été demandé préalablement par le coordinateur
	 * dans le hub.
	 */
	public void createPdfWorkingPlan() {

		try {
			checkInputData();
			setPdfFileToLoad(pdfManager.createPdfWorkingPlan(LoginManagedBean
					.getConnectedUser(), getCriterion().getSillonExtId(),
					getCriterion().getDate(), getCriterion().getTcmsTrainId()));
			setDisplayPdf(true);
		} catch (InputDataException e) {
			MessageUtils.setMessageError(e.getMessage());
		} catch (SillonNotFoundException e) {
			MessageUtils.setMessageInfo("msg.info.nodata");
		} catch (PlanNotFoundException e) {
			MessageUtils.setMessageError("wplan.sillon.nocreate");
		} catch (SillonTypeException e) {
			MessageUtils.setMessageError("plan.sillon.bad.type");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Créationd'un document pdf à partir d'une requête pour rechercher un
	 * programme de formation à partir d'un couple sillon / date ou directement
	 * à partir du tcms-train id. Pas de validator car il s'agit de champs
	 * couplés (on sépare pour être plus lisible). On vérifie par ailleurs que
	 * le programme de formation a bien été demandé préalablement par le
	 * coordinateur dans le hub.
	 */
	public void createPdfFormationPlan() {

		try {
			checkInputData();
			setPdfFileToLoad(pdfManager.createPdfFormationPlan(LoginManagedBean
					.getConnectedUser(), getCriterion().getSillonExtId(),
					getCriterion().getDate(), getCriterion().getTcmsTrainId()));
			setDisplayPdf(true);
		} catch (InputDataException e) {
			MessageUtils.setMessageError(e.getMessage());
		} catch (SillonNotFoundException e) {
			MessageUtils.setMessageInfo("msg.info.nodata");
		} catch (PlanNotFoundException e) {
			MessageUtils.setMessageError("fplan.sillon.nocreate");
		} catch (SillonTypeException e) {
			MessageUtils.setMessageError("plan.sillon.bad.type");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Créationd'un document pdf à partir d'une requête pour rechercher un
	 * relevé de composition à partir d'un couple sillon / date ou directement à
	 * partir du tcms-train id. Pas de validator car il s'agit de champs couplés
	 * (on sépare pour être plus lisible). On vérifie par ailleurs que le relevé
	 * de composition a bien été demandé préalablement par le coordinateur dans
	 * le hub.
	 */
	public void createPdfCompositionPlan() {

		try {
			checkInputData();
			setPdfFileToLoad(pdfManager.createPdfCompositionPlan(
					LoginManagedBean.getConnectedUser(), getCriterion()
							.getSillonExtId(), getCriterion().getDate(),
					getCriterion().getTcmsTrainId()));
			setDisplayPdf(true);
		} catch (InputDataException e) {
			MessageUtils.setMessageError(e.getMessage());
		} catch (SillonNotFoundException e) {
			MessageUtils.setMessageInfo("msg.info.nodata");
		} catch (PlanNotFoundException e) {
			MessageUtils.setMessageError("cplan.sillon.nocreate");
		} catch (SillonTypeException e) {
			MessageUtils.setMessageError("plan.sillon.bad.type");
		} catch (Exception e) {
			getErrorHandler(e);
		}
	}

	/**
	 * Centralisation pour la vérification des critères en entrée (cette méthode
	 * est utilisée pour le panneau de requête concernant le programme de
	 * travail, le programme de formation et le plan de composition.)
	 */
	private void checkInputData() throws ApplicationException {

		if (getCriterion().getDate() == null
				&& getCriterion().getTcmsTrainId().trim().length() == 0
				&& criterion.getSillonExtId().trim().length() == 0)
			throw new InputDataException("plan.data.weak");

		else if ((getCriterion().getDate() != null && getCriterion()
				.getSillonExtId().trim().length() > 0)
				&& criterion.getTcmsTrainId().trim().length() > 0)
			throw new InputDataException("plan.data.weak");

		else if (getCriterion().getTcmsTrainId().trim().length() == 0
				&& (getCriterion().getDate() == null || getCriterion()
						.getSillonExtId().trim().length() == 0))
			throw new InputDataException("plan.data.weak");
	}

	/**
	 * Vérification de la saisie d'une plage horaire. Cette méthode est utilisée
	 * (pour l'instant) pour la recherche de données lors de l'impression du
	 * planning.
	 */
	private void checkTime() throws ApplicationException {

		// On vérifie les heures.
		String time = getCriterion().getTime();
		String timeEnd = getCriterion().getTimeEnd();

		if (time != null && timeEnd != null && time.trim().length() > 0
				&& timeEnd.trim().length() > 0) {
			if ((time.length() > 0 && timeEnd.length() == 0)
					|| (time.length() == 0 && timeEnd.length() > 0)) {
				throw new InputDataException("planning.time.required");
			}
			if (time.length() != 5 || timeEnd.length() != 5)
				throw new InputDataException("planning.time.weak");
		}
	}

	// *********************************
	// Les getters et les setters.
	// *********************************

	public boolean isDisplayPdf() {
		return displayPdf;
	}

	public void setDisplayPdf(boolean displayPdf) {
		this.displayPdf = displayPdf;
	}

	public String getPdfFileToLoad() {
		return pdfFileToLoad;
	}

	public void setPdfFileToLoad(String pdfFileToLoad) {
		this.pdfFileToLoad = pdfFileToLoad;
	}

	public Criterion getCriterion() {
		return criterion;
	}

	public void setCriterion(Criterion criterion) {
		this.criterion = criterion;
	}
}
